package com.ck.chuangke.service.impl;

import java.io.File;
import java.io.IOException;
import java.rmi.ServerException;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.ck.chuangke.service.CkUpgradeService;
import com.ck.common.service.OperationLogService;
import com.ck.constant.BusinessConstant;
import com.ck.constant.ModuleConstant;
import com.ck.constant.PageConstant;
import com.ck.dao.DeviceUpgradeMapper;
import com.ck.model.chuangke.vo.CkDeviceUpgradeListVO;
import com.ck.model.chuangke.vo.CkDeviceUpgradeVO;
import com.ck.model.common.DeviceUpgrade;
import com.ck.model.common.OperationLog;
import com.ck.model.common.User;
import com.ck.model.common.page.PageInfo;
import com.ck.util.BeanUtils;
import com.ck.util.FileUtils;
import com.ck.util.HuaWeiCloudUtils;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import net.dongliu.apk.parser.ApkFile;
import net.dongliu.apk.parser.bean.ApkMeta;

/**
 * 终端升级Service实现类
 */
@Service(value = "ckUpgradeService")
public class CkUpgradeServiceImpl implements CkUpgradeService {
	@Autowired
	private DeviceUpgradeMapper deviceUpgradeMapper;
	@Autowired
	private OperationLogService operationLogService;

	/**
	 * 通过对应机型获取终端升级
	 * getDeviceUpgradeByModel
	 *
	 * @param model 对应机型
	 * @return DeviceUpgrade
	 */
	@Override
	public DeviceUpgrade getDeviceUpgradeByModel(String model) {
		return deviceUpgradeMapper.getDeviceUpgradeByModel(model);
	}

	/**
	 * 保存终端升级
	 *
	 * @param deviceUpgrade DeviceUpgrade对象
	 * @param user
	 * @param operationIP
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void saveDeviceUpgrade(DeviceUpgrade deviceUpgrade, User user, String operationIP) {
		deviceUpgrade.setAddTime(System.currentTimeMillis());
		deviceUpgrade.setUpdateTime(System.currentTimeMillis());
		deviceUpgrade.setActive(BusinessConstant.DEVICE_UPGRADE_FORCE_NO);
		deviceUpgrade.setUploader(user.getUserName());
		deviceUpgradeMapper.saveDeviceUpgrade(deviceUpgrade);
		
		// 保存操作日志
		String module = "";
		String keywords = "";
		if ( BusinessConstant.DEVICE_UPGRADE_TYPE_FIRMWARE == deviceUpgrade.getUpgradeType() ) {
			module = ModuleConstant.MODULE_SYSTEM + "-" + ModuleConstant.MODULE_FIRMWARE_MNG;
			keywords = "添加固件：[" +deviceUpgrade.getUpgradeName() + "]";
		} else {
			module = ModuleConstant.MODULE_SYSTEM + "-" + ModuleConstant.MODULE_SOFTWARE_MNG;
			keywords = "添加APK：[" +deviceUpgrade.getUpgradeName() + "]";
		}
		saveLog(operationIP, user, keywords ,module);
	}

	/**
	 * 获取终端升级分页列表
	 *
	 * @param upgradeType  固件或软件
	 * @param pageNum  当前页
	 * @param pageSize 每页显示条数
	 * @return Page<DeviceUpgrade>
	 */
	@Override
	public PageInfo<CkDeviceUpgradeListVO> listDeviceUpgradeByPage(Integer upgradeType, Integer pageNum, Integer pageSize) {
		pageNum = pageNum == null ? PageConstant.DEFAULT_PAGE_NUM : pageNum;
		pageSize = pageSize == null ? PageConstant.DEFAULT_PAGE_SIZE : pageSize;
		PageHelper.startPage(pageNum, pageSize);
		Page<CkDeviceUpgradeListVO> page = deviceUpgradeMapper.listDeviceUpgradeByPage(upgradeType);
		if (page == null) {
			return new PageInfo<>(pageNum, pageSize, 0, Lists.newArrayList());
		}
		//把Page转化为PageInfo
		PageInfo<CkDeviceUpgradeListVO> pageInfo = new PageInfo<>();
		pageInfo.setPageNum(pageNum);
		pageInfo.setPageSize(pageSize);
		pageInfo.setTotal(page.getTotal());
		pageInfo.setList(page.getResult());
		return pageInfo;
	}

	/**
	 * 获取所有版本号
	 *
	 * @return List<String>
	 */
	@Override
	public List<String> listAllVersionCode() {
		return deviceUpgradeMapper.listAllVersionCode();
	}

	/**
	 * 获取所有版本号
	 *
	 * @return List<String>
	 */
	@Override
	public List<String> listAllVersionName() {
		return deviceUpgradeMapper.listAllVersionName();
	}

	/**
	 * 通过ID获取终端升级
	 *
	 * @param deviceUpgradeId 终端升级ID
	 * @return TbDeviceUpgrade
	 */
	@Override
	public DeviceUpgrade getDeviceUpgradeById(Long deviceUpgradeId) throws ServerException {
		if (deviceUpgradeId == null) {
			throw new ServerException("终端升级ID不能为空");
		}
		return deviceUpgradeMapper.getDeviceUpgradeById(deviceUpgradeId);
	}

	/**
	 * 更新终端升级
	 *
	 * @param deviceUpgrade TbDeviceUpgrade
	 * @param operationIp
	 */
	@Override
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void updateDeviceUpgrade(DeviceUpgrade deviceUpgrade,User user,String operationIp) throws ServerException {
		DeviceUpgrade oldDeviceUpgrade = getDeviceUpgradeById(deviceUpgrade.getDeviceUpgradeId());
		oldDeviceUpgrade.setUrl(deviceUpgrade.getUrl());
		oldDeviceUpgrade.setUpgradeName(deviceUpgrade.getUpgradeName());
		oldDeviceUpgrade.setVersionName(deviceUpgrade.getVersionName());
		oldDeviceUpgrade.setSize(deviceUpgrade.getSize());
		oldDeviceUpgrade.setMd5(deviceUpgrade.getMd5());
		oldDeviceUpgrade.setModelName(deviceUpgrade.getModelName());
		oldDeviceUpgrade.setDescription(deviceUpgrade.getDescription());
		oldDeviceUpgrade.setVersionCode(deviceUpgrade.getVersionCode());
		oldDeviceUpgrade.setUpdateTime(System.currentTimeMillis());
		deviceUpgradeMapper.updateDeviceUpgrade(oldDeviceUpgrade);
		
		// 保存操作日志
		String module = "";
		String keywords = "";
		if ( BusinessConstant.DEVICE_UPGRADE_TYPE_FIRMWARE == oldDeviceUpgrade.getUpgradeType() ) {
			module = ModuleConstant.MODULE_SYSTEM + "-" + ModuleConstant.MODULE_FIRMWARE_MNG;
			keywords = "更新固件：[" +deviceUpgrade.getUpgradeName() + "]";
		} else {
			module = ModuleConstant.MODULE_SYSTEM + "-" + ModuleConstant.MODULE_SOFTWARE_MNG;
			keywords = "更新APK：[" +deviceUpgrade.getUpgradeName() + "]";
		}
		saveLog(operationIp, user, keywords ,module);
	}

	@Override
	public CkDeviceUpgradeVO getDeviceUpgradeByIdVo(Long deviceUpgradeId) {
		DeviceUpgrade deviceUpgrade = deviceUpgradeMapper.getDeviceUpgradeById(deviceUpgradeId);
		if(deviceUpgrade != null){
			CkDeviceUpgradeVO deviceUpgradeVO = new CkDeviceUpgradeVO();
			BeanUtils.copyProperties(deviceUpgradeVO, deviceUpgrade, true);
			if(StringUtils.isNotBlank(deviceUpgrade.getModelName())) {
				deviceUpgradeVO.setModel(Arrays.asList(deviceUpgrade.getModelName().split(",")));
			}
			return deviceUpgradeVO;
		}
		return null;
	}
	
	private void saveLog(String operationIp,User user,String keyWords,String module) {
		// 保存操作日志
		OperationLog operationLog = new OperationLog();
		operationLog.setOperationContent(keyWords);
		operationLog.setOperationModule(module);
		operationLog.setOperationStatus(BusinessConstant.OPERATION_LONG_OPERATION_STATUS_SUCCESS);
		operationLog.setOperationTime(System.currentTimeMillis());
		operationLog.setUserName(user.getUserName());
		operationLog.setRealname(user.getRealname());
		operationLog.setCopmanyCode(user.getCompanyCode());
		operationLog.setOperationIp(operationIp);
		operationLogService.saveOperationLog(operationLog);
	}
	
	/**
	 * 保存文件(如果要返回文件的下载信息，需要传入下载文件路径和封装分析消息的Map)
	 * @param file  MultipartFile
	 * @throws IOException
	 */
	@Override
	public Map<Object, Object> saveApkFile(MultipartFile file) throws IOException {
		//返回信息Map
		Map<Object, Object> msgMap = Maps.newHashMap();
		//上传文件到华为云,返回文件保存地址
		String fileSaveURL = HuaWeiCloudUtils.uploadFile2HuaweiCloud(file, BusinessConstant.FILE_APK_RELATIVE_PATH);
		if (StringUtils.isBlank(fileSaveURL)) {
			throw new ServerException("上传文件到华为云失败");
		}
		//将MultipartFile转为File
		File apkFile = FileUtils.multipartFileConvertFile(file);
		//获取apk信息,自动关闭流
		try (ApkFile apk = new ApkFile(apkFile)) {
			ApkMeta apkMeta = apk.getApkMeta();
			String apkFileMD5 = FileUtils.getFileMD5(apkFile);
			msgMap.put("md5", apkFileMD5);
			msgMap.put("name", apkMeta.getName());
			msgMap.put("versionCode", apkMeta.getVersionCode());
			msgMap.put("versionName", apkMeta.getVersionName());
			double size = file.getSize() / 1024.00 / 1024;
			DecimalFormat decimalFormat  =   new  DecimalFormat("##0.00");
			msgMap.put("size", decimalFormat.format(size));
		}
		//删除因MultipartFile转化为File后，创建的本地File文件
		if (apkFile.exists()) {
			apkFile.delete();
		}
		msgMap.put("fileURL", buildPathName(fileSaveURL));
		msgMap.put("filename", file.getOriginalFilename());
		return msgMap;
	}
	
	/**
	 * 保存固件文件
	 *
	 * @param files
	 * @return
	 * @throws IOException
	 */
	@Override
	public Map<Object, Object> saveFirmwareFile(MultipartFile files) throws IOException {
		
		//文件上传
		String fileSaveURL = HuaWeiCloudUtils.uploadFile2HuaweiCloud(files, BusinessConstant.FILE_FIRMWARE_RELATIVE_PATH);
		if (StringUtils.isBlank(fileSaveURL)) {
            throw new ServerException("上传固件文件到华为云失败");
		}
		//文件完整路径
		Map<Object, Object> msgMap = Maps.newHashMap();
		//获取文件大小
		double size = files.getSize() / 1024.00 / 1024;
		DecimalFormat decimalFormat  =   new  DecimalFormat("##0.00");
		msgMap.put("size", decimalFormat.format(size));
        msgMap.put("fileURL", buildPathName(fileSaveURL));
        msgMap.put("filename", files.getOriginalFilename());
		return msgMap;
	}

	private String buildPathName(String contextFileName) {
		return contextFileName.toString().replace("\\", "/");
	}
}
